import { HttpException, Injectable } from '@nestjs/common';
import { AuthDto } from 'src/dto/auth.dto';
import { User } from 'src/entity/user.entity';
import { JwtService } from '@nestjs/jwt';
import * as argon2 from 'argon2';
import { AuthStoreRegisterDto } from 'src/dto/authStoreRegister.dto';
import { getRandomString } from 'src/common/utils';
import * as dayjs from 'dayjs';
import { DataSource } from 'typeorm';

const TOKEN_SECRET = process.env.TOKEN_SECRET;

@Injectable()
export class AuthService {
  constructor(
    private dataSource: DataSource,
    private readonly jwtService: JwtService,
  ) {}

  /** 生成token */
  private generateToken({ id }: User) {
    return {
      token: this.jwtService.sign(
        {
          id,
        },
        { secret: TOKEN_SECRET },
      ),
    };
  }

  async authLogin(request: any) {
    // 解析token
    let token = request.headers.token;

    if (!token) {
      return 'passed';
    } else {
      let data = this.jwtService.decode(token);

      let now = new Date().getTime() / 1000;

      if (now > Number(data.iat) + 60 * 60 * 24) {
        return 'passed';
      } else {
        return 'ok';
      }
    }
  }

  async enterEmail(uid: any, email: any) {
    let user = await User.findOneBy({ id: uid });
    if (user && user.email == email) {
      user.emailEnter = true;
      await user.save();
      return 'ok';
    } else {
      throw new HttpException('El buzón no coincide', 402);
    }
  }

  async signup(authDto: AuthDto) {
    if (!authDto.username || !authDto.password) {
      throw new HttpException('用户不存在', 400);
    }

    let user = await User.findOne({
      where: { username: authDto.username },
    });

    if (user == null) {
      throw new HttpException('用户不存在', 400);
    }

    if (await argon2.verify(user.password, authDto.password)) {
      let token = this.generateToken(user);
      return token;
    }

    throw new HttpException('登陆失败', 400);
  }

  async register(authDto: AuthDto) {
    let queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.startTransaction();

    try {
      let user = await User.findOneBy({ username: authDto.username });

      if (user != null) {
        throw new HttpException('用户不存在', 400);
      }

      // 生成密码
      let password = await argon2.hash(authDto.password);

      // 创建用户
      let newUser = new User();

      newUser.username = authDto.username;
      newUser.password = password;
      newUser.email = authDto.username;

      newUser.name = 'Callesetas';
      newUser.inviteCode = getRandomString(6);

      newUser.createTime = new Date();
      newUser.updateTime = new Date();
      await newUser.save();

      // 判断authDto中是否有inviteCode 绑定注册用户
      if (authDto.inviteCode) {
        // 查询用户
        let user1 = await User.findOneBy({ inviteCode: authDto.inviteCode });
        if (user1 != null) {
          newUser.inviteId = user1.id;
          await newUser.save();
        }
      } else {
        newUser.inviteId = 4;
        await newUser.save();
      }

      return { id: newUser.id, username: newUser.username };
    } catch (error) {
      await queryRunner.rollbackTransaction();

      throw new HttpException(error.response, error.status);
    } finally {
      await queryRunner.release();
    }
  }

  async registerStore(authDto: AuthStoreRegisterDto) {
    let user = await User.findOneBy({ username: authDto.username });

    if (user != null) {
      throw new HttpException('账号已注册', 400);
    }

    // 生成密码
    let password = await argon2.hash(authDto.password);

    // 创建用户
    let newUser = new User();

    newUser.password = password;
    newUser.name = 'Callesetas';
    newUser.inviteCode = getRandomString(6);

    // 判断authDto中是否有inviteCode 绑定注册用户
    if (authDto.inviteCode) {
      // 查询用户
      let user1 = await User.findOneBy({ inviteCode: authDto.inviteCode });
      if (user1 != null) {
        newUser.inviteId = user1.id;
        await newUser.save();
      }
    } else {
      newUser.inviteId = 4;
      await newUser.save();
    }

    return { id: newUser.id, username: newUser.username };
  }

  // 忘记密码邮件
  async lostPassword(phone: string) {
    let user = await User.findOne({ where: { phone } });
    if (!user) {
      throw new HttpException('用户不存在', 400);
    }
    // 生成验证码
    let authCode = this.jwtService.sign(
      {
        id: user.id,
      },
      { secret: TOKEN_SECRET },
    );
    // 发送邮件
  }

  async changePassword(uid: string, authCode: string, password: string) {
    let user = await User.findOneBy({ id: +uid });
    let data = this.jwtService.decode(authCode);

    if (data.id == user.id) {
      // 验证密码
      user.password = await argon2.hash(password);
      await user.save();

      return;
    } else {
      throw new HttpException('账号密码不一致', 400);
    }
  }
}
